/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.mochaccino.framework.scheduler;

import com.google.common.base.Preconditions;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.quartz.Calendar;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerMetaData;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerKey;
import org.quartz.UnableToInterruptJobException;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Quartz Scheduler Wrapper that remove calls that are related
 * to the scheduler lifecycles. Leaving only the pre
 */
@Singleton
public class JobScheduler {
	private Logger logger = LoggerFactory.getLogger(  getClass() );

	/** The Actual Quartz Scheduler */
	private Scheduler delegate = null;

	/** Wait for Jobs to complete on shutdown? */
	private boolean waitForJobsToComplete = true;

	/** Constructor */
	@Inject
	public JobScheduler( Scheduler delegate ) {
		this( delegate, true );
	}

	/** Constructor */
	public JobScheduler( Scheduler delegate, boolean waitForJobsToComplete ) {
		this.delegate = Preconditions.checkNotNull( delegate );
		this.waitForJobsToComplete = waitForJobsToComplete;
	}

	/** @see org.quartz.Scheduler#addCalendar(java.lang.String, org.quartz.Calendar, boolean, boolean) */
	public void addCalendar( String calName, Calendar calendar, boolean replace, boolean updateTriggers ) throws SchedulerException {
		delegate.addCalendar( calName, calendar, replace, updateTriggers );
	}

	/** @see org.quartz.Scheduler#addJob(org.quartz.JobDetail, boolean) */
	public void addJob( JobDetail jobDetail, boolean replace ) throws SchedulerException {
		delegate.addJob( jobDetail, replace );
	}

	/** @see org.quartz.Scheduler#checkExists(org.quartz.JobKey) */
	public boolean checkExists( JobKey jobKey ) throws SchedulerException {
		return delegate.checkExists( jobKey );
	}

	/** @see org.quartz.Scheduler#checkExists(org.quartz.JobKey) */
	public boolean checkExists( TriggerKey triggerKey ) throws SchedulerException {
		return delegate.checkExists( triggerKey );
	}

	/** @see org.quartz.Scheduler#deleteCalendar(java.lang.String) */
	public boolean deleteCalendar( String calName ) throws SchedulerException {
		return delegate.deleteCalendar( calName );
	}

	/** @see org.quartz.Scheduler#deleteJob(org.quartz.JobKey) */
	public boolean deleteJob( JobKey jobKey ) throws SchedulerException {
		return delegate.deleteJob( jobKey );
	}

	/** @see org.quartz.Scheduler#deleteJobs(java.util.List<org.quartz.JobKey>) */
	public boolean deleteJobs( List<JobKey> jobKeys ) throws SchedulerException {
		return delegate.deleteJobs( jobKeys );
	}

	/** @see org.quartz.Scheduler#getCalendar(java.lang.String) */
	public Calendar getCalendar( String calName ) throws SchedulerException {
		return delegate.getCalendar( calName );
	}

	/** @see org.quartz.Scheduler#getCalendarNames() */
	public List<String> getCalendarNames() throws SchedulerException {
		return delegate.getCalendarNames();
	}

	/** @see org.quartz.Scheduler#getCurrentlyExecutingJobs() */
	public List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException {
		return delegate.getCurrentlyExecutingJobs();
	}

	/** @see org.quartz.Scheduler#getJobDetail(org.quartz.JobKey) */
	public JobDetail getJobDetail( JobKey jobKey ) throws SchedulerException {
		return delegate.getJobDetail( jobKey );
	}

	/** @see org.quartz.Scheduler#getJobGroupNames() */
	public List<String> getJobGroupNames() throws SchedulerException {
		return delegate.getJobGroupNames();
	}

	/** @see org.quartz.Scheduler#getJobKeys(org.quartz.impl.matchers.GroupMatcher<org.quartz.JobKey>) */
	public Set<JobKey> getJobKeys( GroupMatcher<JobKey> matcher ) throws SchedulerException {
		return delegate.getJobKeys( matcher );
	}

	/** @see org.quartz.Scheduler#getMetaData() */
	public SchedulerMetaData getMetaData() throws SchedulerException {
		return delegate.getMetaData();
	}

	/** @see org.quartz.Scheduler#getPausedTriggerGroups() */
	public Set<String> getPausedTriggerGroups() throws SchedulerException {
		return delegate.getPausedTriggerGroups();
	}

	/** @see org.quartz.Scheduler#getTrigger(org.quartz.TriggerKey) */
	public Trigger getTrigger( TriggerKey triggerKey ) throws SchedulerException {
		return delegate.getTrigger( triggerKey );
	}

	/** @see org.quartz.Scheduler#getTriggerGroupNames() */
	public List<String> getTriggerGroupNames() throws SchedulerException {
		return delegate.getTriggerGroupNames();
	}

	/** @see org.quartz.Scheduler#getTriggerKeys(org.quartz.impl.matchers.GroupMatcher<org.quartz.TriggerKey>) */
	public Set<TriggerKey> getTriggerKeys( GroupMatcher<TriggerKey> matcher ) throws SchedulerException {
		return delegate.getTriggerKeys( matcher );
	}

	/** @see org.quartz.Scheduler#getTriggerState(org.quartz.TriggerKey) */
	public TriggerState getTriggerState( TriggerKey triggerKey ) throws SchedulerException {
		return delegate.getTriggerState( triggerKey );
	}

	/** @see org.quartz.Scheduler#getTriggersOfJob(org.quartz.JobKey) */
	public List<? extends Trigger> getTriggersOfJob( JobKey jobKey ) throws SchedulerException {
		return delegate.getTriggersOfJob( jobKey );
	}

	/** @see org.quartz.Scheduler#interrupt(org.quartz.JobKey) */
	public boolean interrupt( String fireInstanceId ) throws UnableToInterruptJobException {
		return delegate.interrupt( fireInstanceId );
	}

	/** @see org.quartz.Scheduler#interrupt(org.quartz.JobKey) */
	public boolean interrupt( JobKey jobKey ) throws UnableToInterruptJobException {
		return delegate.interrupt( jobKey );
	}

	/** @see org.quartz.Scheduler#pauseAll() */
	public void pauseAll() throws SchedulerException {
		delegate.pauseAll();
	}

	/** @see org.quartz.Scheduler#pauseJob(org.quartz.JobKey)s */
	public void pauseJob( JobKey jobKey ) throws SchedulerException {
		delegate.pauseJob( jobKey );
	}

	/** @see org.quartz.Scheduler#pauseJobs */
	public void pauseJobs( GroupMatcher<JobKey> matcher ) throws SchedulerException {
		delegate.pauseJobs( matcher );
	}

	/** @see org.quartz.Scheduler#pauseTrigger(org.quartz.TriggerKey) */
	public void pauseTrigger( TriggerKey triggerKey ) throws SchedulerException {
		delegate.pauseTrigger( triggerKey );
	}

	/** @see org.quartz.Scheduler#pauseTriggers(org.quartz.impl.matchers.GroupMatcher<org.quartz.TriggerKey>) */
	public void pauseTriggers( GroupMatcher<TriggerKey> matcher ) throws SchedulerException {
		delegate.pauseTriggers( matcher );
	}

	/** @see org.quartz.Scheduler#rescheduleJob(org.quartz.TriggerKey, org.quartz.Trigger) */
	public Date rescheduleJob( TriggerKey triggerKey, Trigger newTrigger ) throws SchedulerException {
		return delegate.rescheduleJob( triggerKey, newTrigger );
	}

	/** @see org.quartz.Scheduler#resumeJob(org.quartz.JobKey) */
	public void resumeAll() throws SchedulerException {
		delegate.resumeAll();
	}

	/** @see org.quartz.Scheduler#resumeJob(org.quartz.JobKey) */
	public void resumeJob( JobKey jobKey ) throws SchedulerException {
		delegate.resumeJob( jobKey );
	}

	/** @see org.quartz.Scheduler#resumeJobs(org.quartz.impl.matchers.GroupMatcher<org.quartz.JobKey>) */
	public void resumeJobs( GroupMatcher<JobKey> matcher ) throws SchedulerException {
		delegate.resumeJobs( matcher );
	}

	/** @see org.quartz.Scheduler#resumeTrigger(org.quartz.TriggerKey) */
	public void resumeTrigger( TriggerKey triggerKey ) throws SchedulerException {
		delegate.resumeTrigger( triggerKey );
	}

	/** @see org.quartz.Scheduler#resumeTriggers(org.quartz.impl.matchers.GroupMatcher<org.quartz.TriggerKey>) */
	public void resumeTriggers( GroupMatcher<TriggerKey> matcher ) throws SchedulerException {
		delegate.resumeTriggers( matcher );
	}

	/** @see org.quartz.Scheduler#scheduleJob(org.quartz.JobDetail, org.quartz.Trigger) */
	public Date scheduleJob( JobDetail jobDetail, Trigger trigger ) throws SchedulerException {
		return delegate.scheduleJob( jobDetail, trigger );
	}

	/** @see org.quartz.Scheduler#scheduleJob(org.quartz.JobDetail, org.quartz.Trigger) */
	public Date scheduleJob( Trigger trigger ) throws SchedulerException {
		return delegate.scheduleJob( trigger );
	}

	/** @see org.quartz.Scheduler#scheduleJobs(java.util.Map<org.quartz.JobDetail,java.util.List<org.quartz.Trigger>>, boolean) */
	public void scheduleJobs( Map<JobDetail,List<Trigger>> triggersAndJobs, boolean replace ) throws SchedulerException {
		delegate.scheduleJobs( triggersAndJobs, replace );
	}

	/** @see org.quartz.Scheduler#shutdown() */
	@PreDestroy
	public void shutdown()  {
		try {
			delegate.shutdown( this.waitForJobsToComplete );
		} catch ( SchedulerException e ) {
			logger.error( e.getMessage(), e);
		}
	}

	/** @see org.quartz.Scheduler#start() */
	@PostConstruct
	public void start()  {
		try {
			delegate.start();
		} catch ( SchedulerException e ) {
			logger.error( e.getMessage(), e );
		}
	}

	/** @see org.quartz.Scheduler#triggerJob(org.quartz.JobKey) */
	public void triggerJob( JobKey jobKey ) throws SchedulerException {
		delegate.triggerJob( jobKey );
	}

	/** @see org.quartz.Scheduler#triggerJob(org.quartz.JobKey) */
	public void triggerJob( JobKey jobKey, JobDataMap data ) throws SchedulerException {
		delegate.triggerJob( jobKey, data );
	}

	/** @see org.quartz.Scheduler#unscheduleJob(org.quartz.TriggerKey) */
	public boolean unscheduleJob( TriggerKey triggerKey ) throws SchedulerException {
		return delegate.unscheduleJob( triggerKey );
	}

	/** @see org.quartz.Scheduler#unscheduleJobs(java.util.List<org.quartz.TriggerKey>) */
	public boolean unscheduleJobs( List<TriggerKey> triggerKeys ) throws SchedulerException {
		return delegate.unscheduleJobs( triggerKeys );
	}
}
